/*
 * 移动应用本地数据库缓存
 * html5 webSqlite数据库
 * 
 * 本文件中所有的以'_'符号开头的方法被认为是private的方法或属性，不对外部公开的。
 * 如果外部使用了以'_'符号开头的方法或属性，一旦出现问题将由使用者自己解决。
 * 
 * by yezhanwang 2013.10.28
 * 
 */

jQuery.fn.websqliteOptions={};
//websqlite工具类
Newtouch.webSqliteUtil={
		//获取当前数据库
		database:null,
		//默认数据库参数
		databaseOptions:$.extend({
			name:'newtouchMobile',
			version:'1.0',
			comment:'web sqlite 数据库',
			size :1024 * 1024 * 10  // 10MB
	
		},jQuery.fn.websqliteOptions),
		/*
		 * 创建数据库
		 * 示例:Newtouch.webSqliteUtil.initDataBase()
		 * 数据库只打开一次，不会重复打开
		 */
		initDataBase:function(options){
			 try {  
			        if (!window.openDatabase) {  
			            console.log('Databases are not supported in this browser.');  
			        } else {  
			        	//如果数据库不存在，就重新创建，否则调用已有数据库
			        	if (!Newtouch.webSqliteUtil.database) {
								Newtouch.webSqliteUtil.database = openDatabase(Newtouch.webSqliteUtil.databaseOptions.name, Newtouch.webSqliteUtil.databaseOptions.version, Newtouch.webSqliteUtil.databaseOptions.comment, Newtouch.webSqliteUtil.databaseOptions.size, function() {
							             //success
//									   console.log(Newtouch.webSqliteUtil.databaseOptions);
								});
						}
						// 不能打开数据库，可能浏览器不支持 openDatabase，或容量设置太大了
						if (!Newtouch.webSqliteUtil.database) {
							console.error(logPrefix + 'openDatabase error.', Newtouch.webSqliteUtil.databaseOptions.name, Newtouch.webSqliteUtil.databaseOptions.version,
									Newtouch.webSqliteUtil.databaseOptions.comment, Newtouch.webSqliteUtil.databaseOptions.size);
						}
			        	
			        }  
			    } catch(e) {  
			        if (e == 2) {  
			            // Version number mismatch.  
			            console.log("Invalid database version.");  
			        } else {  
			            console.log("Unknown error "+e+".");  
			        }  
			        return;  
			    }  
			
		},
		 /**
		 * 
		 * settings 是一个键值对集合。 
		 * sql          : sql语句
		 * clazz        : {tableName:"",columns:[]} 
		 * 
		 * success    : function   成功回调函数 
		 * error      : function   失败回调函数 
		 * 
		 *  创建表格
		 *  示例:
		 *  Newtouch.webSqliteUtil.createTables({
		 *  			sql:"CREATE TABLE  IF NOT EXISTS people(id int,name text)",
		 *  			success:function(){
		 *  			},
		 *  			error:function(t,e){
		 *  			}
		 *  );
		 *  
		 */
		createTables:function(settings){
			//sql语句："CREATE TABLE test (id int UNIQUE, mytitle TEXT, timestamp REAL)"
			try{
				Newtouch.webSqliteUtil.database.transaction(function(tx) {
					if(typeof settings.sql =="string")
						 tx.executeSql(settings.sql,[],settings.success,settings.error);
					else if(settings.clazz){
						 var cols=[];
						 for(var i=0;i<settings.clazz.columns.length;i++){
							 cols.push(settings.clazz.columns[i]);
							 
						 }
//						 console.log("CREATE TABLE IF NOT EXISTS "+settings.clazz.tableName+"("+cols.join(",")+")")
						 tx.executeSql("CREATE TABLE IF NOT EXISTS "+settings.clazz.tableName+"("+cols.join(",")+")",[],settings.success,settings.error);
					}
				});
			}catch(e){  
		        if (e == 2) {  
		            // Version number mismatch.  
		            console.log("Invalid database version.");  
		        } else {  
		            console.log("Unknown error "+e+".");  
		        }  
		        return;  
		    }  
			
		},
		/**
		 * 执行一条或多条查询。
		 * 
		 * settings 是一个键值对集合。 
		 * sql        : ""/[]      SQL 语句 (require)
		 * params     : []/[[]]    参数 (optional)
		 * success    : function   成功回调函数 (optional) - 传入以下参数：r 或 无
		 * error      : function   失败回调函数 (t,e) - 传入以下参数：e
		 * 
		 * 如果 sql 是 "" 类型，那么 params 必须是 [] 类型。
		 * 如果 sql 是 [] 类型，那么 params 必须是 [[]] 类型，且长度与 sql 一致。
		 * 如果 sql 是 [] 类型，那么 success 成功回调函数不传参数。
		 * 
		 * 示例：
		 * Newtouch.webSqliteUtil.queryData({
		 *     sql      : 'select count(*) as cnt from sqlite_master where tbl_name = ?',
		 *     params   : [ tableName ],
		 *     success  : function(r) {
		 *         if (r.rows.item(0).cnt == 1) {
		 *             console.log(tableName, '存在');
		 *         }else{
		 *             console.log(tableName, '不存在');
		 *         }
		 *     }
		 * });
		 */
		queryData:function(settings){
			if(!settings || !settings.sql || settings.sql.length <= 0){
				console.log('db.query: 基本参数错误');
				return;
			}
			var sql = [],params = [];
			if(settings.sql instanceof Array){
				sql = settings.sql;
				if(!(settings.params instanceof Array)){
					console.log('db.query: 参数对应错误');
					return;
				}
				if(sql.length != settings.params.length){
					console.log('db.query: 参数对应错误');
					return;				
				}
				for(var i = 0; i < settings.params.length; i++){
					if(!settings.params[i]){
						settings.params[i]=[];continue;
					}
					if(!(settings.params[i] instanceof Array)){
						console.log('db.query: 参数对应错误');
						return;					
					}
				}
			}else{
				settings.params = settings.params||[];
				params.push(settings.params);
			}
			
				Newtouch.webSqliteUtil.database.readTransaction(function(t) {
					Newtouch.webSqliteUtil._executeSql(settings, t);
				});
			
		},
		/**
		 * 插入或更新记录。
		 * 
		 * settings 是一个键值对集合。
		 * clazz       {table : "", columns: []}  类型 (require)
		 * data        {}/[{},{}..]  保存的数据 (require)
		 * success     function      成功回调函数 (optional) - 当所有语句执行完，执行成功回调函数
		 * error       function      错误回调函数 (t,e) - 若 stopOnFail 为 true，发生错误时执行错误回调函数并终止
		 * 
		 * 示例：
		 * var settings = {
				clazz: {table : "tb_policy_applicant", columns : [ "birthday", "occu_code_owner", "name",
						"benef_relat_insured", "nationality", "benef_id_type",
						"papers_num", "sex", "education", "marital_status",
						"domiciliary", " address", "post", "company", "webSqliteUtil",
						"phone", "email", "area_code" ]},
				data : {id: 1, birthday : "2012-3-1", maritalStatus : 1, occuCodeOwner: "123"},
				success : function(){
					console.debug("save success");
				}
			};
			
			Newtouch.webSqliteUtil.saveData(settings);
		 */
		saveOrUpdateData:function(settings){
				Newtouch.webSqliteUtil._browserSave(settings);
		},
		
		
		deleteData:function(settings){
				Newtouch.webSqliteUtil._browserDelete(settings);
		},
		/** 
         * 查询表的信息 
         * table_name: 表名称，支持 % *， 
         */  
        showTables:function( table_name, callback){  
				try{
					Newtouch.webSqliteUtil.database.transaction(function(tx){
						tx.executeSql("select * from sqlite_master where type='table' and name like ?", [table_name], callback);
						
					});
				}catch(e){
					
					  if (e == 2) {  
				            // Version number mismatch.  
				            console.log("Invalid database version.");  
				        } else {  
				            console.log("Unknown error "+e+".");  
				        }  
				        return;  
				}
             
        },  
        /*
         * 删除表格
         */
		dropTables:function(table_name,callback){
			try{
				Newtouch.webSqliteUtil.database.transaction(  
					        function (t) {  
					            t.executeSql("DROP TABLE "+table_name+";",[],callback);  
					        }  
					    );  
			    console.log("Table '"+table_name+"' has been dropped.");  
			   // location.reload(); 
			}catch(e){
				
				  if (e == 2) {  
			            // Version number mismatch.  
			            console.log("Invalid database version.");  
			        } else {  
			            console.log("Unknown error "+e+".");  
			        }  
			        return;  
				
			}
		
			
		},
		// 执行 sql ： 增删改查、DDL。
		_executeSql:function(settings, t) {
			if (!settings || !settings.sql) {
				return;
			}
			var sql = settings.sql;
			var params = settings.params;
			var success = settings.success;
			var error = settings.error;

			// 依次执行多条 sql，因为 db 是异步的，通过递归实现依次执行
			// 参数 params 是二维数组
			if ($.isArray(sql) && sql.length > 0) {
				executeMutilSql();
				return;
			}

			if (typeof (sql) == "string") {
				executeOneSql(sql, params, success, error);
				return;
			}

			// 数据类型不正确，不做任何处理
			return;

			// 执行一条 sql
			function executeOneSql(sql, params, success, error) {

				t.executeSql(sql, params, function(t, r) {
					console.log(sql);
					if ($.isFunction(success)) {
						success(r);
					}
				}, function(t, e) {
					console.error('> > error > >'+sql);
					if ($.isFunction(error)) {
						error(e);
					}
				});
			}

			// 依次执行多条 sql
			function executeMutilSql() {
				// 如果一条 sql 执行失败，是否中断，true 中断，false 继续执行下一条
				var stopOnFail = settings.stopOnFail;
				// sql 索引，sql[i] 即为当前 sql
				var i = 0;
				// 开始执行第一条 sql
				executeNextSql();

				// 递归回调依次执行 sql，全部执行完调用成功或失败回调函数
				function executeNextSql() {
					executeOneSql(sql[i], getParams(), function(r) {
						if (next()) {
							executeNextSql();
						} else {
							if ($.isFunction(success)) {
								success();
							}
						}
					}, function(e) {
						if (stopOnFail) {
							if ($.isFunction(error)) {
								error(e);
							}
							return;
						}

						if (next()) {
							executeNextSql();
							return;
						}

						if ($.isFunction(success)) {
							success();
						}
					});
				}

				// 将索引定位到下一条 sql，如果有下一条 sql 返回 true，否则返回 false
				function next() {
					i++;
					return i < sql.length;
				}

				// 当前 sql 的参数
				function getParams() {
					if (params && $.isArray(params[i])) {
						return params[i];
					}
					return null;
				}
			}// <- end executeMutilSql
		},// <- end executeSql
		_browserSave : function(settings){
			// 执行一条
			if (!$.isArray(settings.data)) {
				Newtouch.webSqliteUtil._internalSave(settings);
				return;
			}

			// 执行多条
			var index = -1;
			saveNextIfExist();
			return;

			function saveNextIfExist() {
				index++;
				if (index < settings.data.length) {
					Newtouch.webSqliteUtil._internalSave({
						clazz : settings.clazz,
						data : settings.data[index],
						success : function() {
							saveNextIfExist();
						},
						error : function() {
							if (!options.stopOnFail) {
								// 忽略失败
								saveNextIfExist();
							} else {
								// 执行失败回调函数
								if ($.isFunction(settings.error)) {
									settings.error();
								}
							}
						}
					});
				} else {
					// 已全部保存，执行成功回调函数
					if ($.isFunction(settings.success)) {
						settings.success();
					}
				}
			}		
		},
		_browserUpdate : function(settings){
			Newtouch.webSqliteUtil.database.transaction(function(t) {
				Newtouch.webSqliteUtil._executeSql(settings, t);
			});
		},
		_browserDelete:function(settings){
			// 执行一条
			if (!$.isArray(settings.data)) {
				Newtouch.webSqliteUtil._internalDelete(settings);
				return;
			}

			// 执行多条
			var index = -1;
			delNextIfExist();
			return;

			function delNextIfExist() {
				index++;
				if (index < settings.data.length) {
					Newtouch.webSqliteUtil._internalDelete({
						clazz : settings.clazz,
						data : settings.data[index],
						success : function() {
							delNextIfExist();
						},
						error : function() {
							if (!options.stopOnFail) {
								// 忽略失败
								delNextIfExist();
							} else {
								// 执行失败回调函数
								if ($.isFunction(settings.error)) {
									settings.error();
								}
							}
						}
					});
				} else {
					// 已全部保存，执行成功回调函数
					if ($.isFunction(settings.success)) {
						settings.success();
					}
				}
			}		
			
		},
		_internalSave:function(settings) {
			if (settings.data.id) {
				update(settings);
			} else {
				insert(settings);
			}
			function insert(settings) {
				var sql = [], placeholders = [], parameters = [];
				sql.push("insert into " + settings.clazz.table + "(");
				$.each(settings.clazz.columns, function(i, col) {
					var value = settings.data[col];
					
					if (typeof (value) == "undefined" || value === null) {
						return;
					}
					// 数组、普通对象序列化为 JSON
					if(!isBaseTypeOrNull(value)){
						value = JSON.stringify(value);
					}
					
					sql.push(col + ",");
					placeholders.push("?,");
					parameters.push(value);
				});
	
				// 一个值都没有，什么都不做
				if (placeholders.length == 0) {
					return;
				}
	
				// 去掉多余逗号
				var line = sql[sql.length - 1];
				sql[sql.length - 1] = line.substring(0, line.length - 1);
				line = placeholders[placeholders.length - 1];
				placeholders[placeholders.length - 1] = line.substring(0,
						line.length - 1);
	
				sql.push(") values(");
				sql.push(placeholders.join(""));
				sql.push(")");
	
				Newtouch.webSqliteUtil._browserUpdate({
					sql : sql.join(""),
					params : parameters,
					success : function(r) {
						// 新记录的 id
						if ($.isNumeric(r.insertId)) {
							settings.data.id = r.insertId;
						}
						// 回调
						if ($.isFunction(settings.success)) {
							settings.success(r);
						}
					},
					error : settings.error
				});
			}
			function update(settings) {
				var sql = [], noValue = true, parameters = [];

				sql.push("update " + settings.clazz.table + " set ");
				$.each(settings.clazz.columns, function(i, col) {
					var value = settings.data[col];
					if (typeof (value) == "undefined" || value === null) {
						return;
					}
					// 数组、普通对象序列化为 JSON
					if(!isBaseTypeOrNull(value)){
						value = JSON.stringify(value);
					}
					
					if (noValue) {
						noValue = false;
					}
					sql.push(col + "=?,");
					parameters.push(value);
				});
				// 一个值都没有，什么都不做
				if (noValue) {
					return;
				}

				// 去掉多余逗号
				var line = sql[sql.length - 1];
				sql[sql.length - 1] = line.substring(0, line.length - 1);

				var idint = parseInt(settings.data.id,10);
				var idStr = "" + idint;
				sql.push(" where id = ? or id = ?");
				parameters.push(idint);
				parameters.push(idStr);
				
				Newtouch.webSqliteUtil._browserUpdate({
					sql : sql.join(""),
					params : parameters,
					success : settings.success,
					error : settings.error
				});
			}
		},
		_internalDelete:function(settings){
			var sql = [], noValue = true, parameters = [];

			sql.push("delete from " + settings.clazz.table + " where ");
			$.each(settings.clazz.columns, function(i, col) {
				var value = settings.data[col];
				if (typeof (value) == "undefined" || value === null) {
					return;
				}
				// 数组、普通对象序列化为 JSON
				if(!isBaseTypeOrNull(value)){
					value = JSON.stringify(value);
				}
				
				if (noValue) {
					noValue = false;
				}
				sql.push(col + "=?,");
				parameters.push(value);
			});
			// 一个值都没有，什么都不做
			if (noValue) {
				return;
			}

			// 去掉多余逗号
			var line = sql[sql.length - 1];
			sql[sql.length - 1] = line.substring(0, line.length - 1);
			
			Newtouch.webSqliteUtil._browserUpdate({
				sql : sql.join(""),
				params : parameters,
				success : settings.success,
				error : settings.error
			});
		}

		
		
};

(function(){
	
//	//配置本地websqlite数据库
//	jQuery.fn.webSqliteOptions=function(){ return null;};
//		var databaseOptions=$.extend({
//			name:'newtouchOne',
//			version:'1.0',
//			comment:'webSqliteUtil sqlite 数据库',
//			size :1024 * 1024 * 10  // 10M
//
//		},jQuery.fn.webSqliteOptions());
//		
//		
//		var db;//本地数据库
//		var logExit="";
//		
//		function Dao(){};
//		
//		Dao.prototype={
//				getDBConnection:function(){
//					
//					 try {  
//					        if (!window.openDatabase) {  
//					            console.log('Databases are not supported in this browser.');  
//					        } else {  
//					        	if (!db) {
//									db = openDatabase(databaseOptions.name, databaseOptions.version, databaseOptions.comment, databaseOptions.size, function() {
//										//success
//									});
//								}
//								// 不能打开数据库，可能浏览器不支持 openDatabase，或容量设置太大了
//								if (!db) {
//									console.error(logPrefix + 'openDatabase error.', databaseOptions.name, databaseOptions.version,
//											databaseOptions.comment, databaseOptions.size);
//								}
//					        	
//					        }  
//					    } catch(e) {  
//					        if (e == 2) {  
//					            // Version number mismatch.  
//					            console.log("Invalid database version.");  
//					        } else {  
//					            console.log("Unknown error "+e+".");  
//					        }  
//					        return;  
//					    }  
//					return db;
//				}
//				
//				
//				
//		}
//		
	    
//		var dao=new Dao();
//		Newtouch.webSqliteUtil.database=dao.getDBConnection();
	    	
		
		
		
	rowsItemToEntity=function (item, clazz) {
		// 解析为简单对象
		if(!clazz){
			var entity = {};
			for ( var p in item) {
				entity[tb.toCameCase(p)] = item[p];
			}
			return entity;
		}
		// 解析为指定的类型
		var entity = new clazz();
		for ( var p in item) {
			var entityProp = tb.toCameCase(p);
			
			if(!isBaseTypeOrNull(entity[entityProp]) && item[p]){
				// 还原数组或简单对象
				if(item[p] instanceof String){
					entity[entityProp] = JSON.parse(item[p]);
				}else{
					entity[entityProp] = item[p];
				}
			}else{
				// 基本数据类型直接赋值
				entity[entityProp] = item[p];
			}
		}
		return entity;
	}
	
	isBaseTypeOrNull=function (v){
		if (typeof (v) == "undefined" || v === null
				|| typeof (v) == "string" || typeof (v) == "number"
				|| typeof (v) == "boolean") {
			return true;
		}
		
		return false;
	}
})(window);